#define _GNU_SOURCE
#include "app_serial.h"
#include "log/log.h"
//初始化串口属性
int app_serial_init(Device *device)
{
    //设置川口属性
    app_srerial_setBaudrate(device, B9600);//9600波特率
    app_serial_setParity(device, PARITY_NONE);//无校验位
    app_serial_setStopBits(device, SB_1);//1位停止位
    app_serial_setRaw(device);      //设置为原始模式
    // app_serial_setBlock(device, 0);//阻塞模式
    //刷新让所有属性生效
    int result = tcflush(device->fd, TCIOFLUSH);
    if (result != 0)
    {
        log_error("串口初始化失败");
        return -1;
    }
    log_debug("串口初始化成功");
    return 0;
}
//设置波特率
int app_srerial_setBaudrate(Device *device, BraudRate baudrate)
{
    //获取川口属性
    struct termios attr;//川口属性
    tcgetattr(device->fd, &attr);//获取川口属性
    //修改属性 设置波特率
    cfsetspeed(&attr, baudrate);//设置波特率
    //设置川口属性，等待flush生效
    int result = tcsetattr(device->fd, TCSAFLUSH, &attr);
    if (result != 0)
    {
        log_error("设置波特率失败");
        return -1;
    }
    log_debug("设置波特率成功");
    return 0;
}
//设置校验位
int app_serial_setParity(Device *device, Parity parity)
{
     //获取川口属性
     struct termios attr;
     tcgetattr(device->fd, &attr);
     //修改属性
    attr.c_cflag &= ~(PARENB|PARODD);//清除校验位
    attr.c_cflag |= parity; //设置校验位
     //设置川口属性
     int result = tcsetattr(device->fd, TCSAFLUSH, &attr);
     if (result != 0)
     {
         log_error("设置校验位失败");
         return -1;
     }
     log_debug("设置校验位成功");
     return 0;
}
//设置停止位
int app_serial_setStopBits(Device *device, StopBits stopbits)
{
     //获取川口属性
     struct termios attr;
     tcgetattr(device->fd, &attr);
     //修改属性
    attr.c_cflag &= ~CSTOPB;//清除停止位
     attr.c_cflag |= stopbits; //设置停止位
     //设置川口属性
     int result = tcsetattr(device->fd, TCSAFLUSH, &attr);
     if (result != 0)
     {
         log_error("设置停止位失败");
         return -1;
     }
     log_debug("设置停止位成功");
     return 0;
}
//设置是否是阻塞模式
int app_serial_setBlock(Device *device, int is_block)
{
     //获取川口属性
     struct termios attr;
     tcgetattr(device->fd, &attr);//获取川口属性
     //修改属性
    if (is_block == 1)//阻塞模式
    {
        attr.c_cc[VMIN] = 1;//最少读取一个字符,否则阻塞
        attr.c_cc[VTIME] = 0;//没有超时之说
    }
    else
    {
        attr.c_cc[VMIN] = 0;//可以不读字节直接返回
        attr.c_cc[VTIME] = 2;//超时时间：2*0.1s=0.2s
    }
     //设置川口属性
     int result = tcsetattr(device->fd, TCSAFLUSH, &attr);
     if (result != 0)
     {
         log_error("设置串口阻塞失败");
         return -1;
     }
     log_debug("设置串口阻塞成功");
     return 0;
}
//设置原始模式
int app_serial_setRaw(Device *device)
{
     //获取川口属性
     struct termios attr;
     tcgetattr(device->fd, &attr);
     //修改属性
    cfmakeraw(&attr);
     //设置川口属性
     int result = tcsetattr(device->fd, TCSAFLUSH, &attr);
     if (result != 0)
     {
         log_error("设置原始模式失败");
         return -1;
     }
     log_debug("设置原始模式成功");
     return 0;
    
}

